package personal.controller.media;

import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import personal.controller.util.HandlerUtil;
import personal.persistance.dao.AlbumDao;
import personal.persistance.dao.AlbumDetailDao;
import personal.persistance.dao.DaoFactory;
import personal.persistance.dao.ImageDao;
import personal.persistance.model.Album;
import personal.persistance.model.AlbumDetail;
import personal.persistance.model.Image;

/**
 * Image handler
 * @author LocNguyen
 */
public class ImageHandler {
    /****/
    private JSONParser parser = new JSONParser();
    
    /** DAO object definition **/
    private ImageDao imgDao;
    private AlbumDao albumDao;
    private AlbumDetailDao albumDetailDao;
    
    /**
     * Default constructor
     */
    public ImageHandler() {
        imgDao = DaoFactory.getInstance().getImageDao();
        albumDao = DaoFactory.getInstance().getAlbumDao();
        albumDetailDao = DaoFactory.getInstance().getAlbumDetailDao();
    }
    
    public void controlRequest(String cmd, HttpServletRequest request, HttpServletResponse response) {
        if ((cmd == null) || cmd.isEmpty()) {
            return;
        }
        
        if (cmd.equalsIgnoreCase("add_image")) {
            String data = request.getParameter("data");
            JSONObject json = new JSONObject();
            try {
                Image img = getImage(data);
                int imgId = imgDao.add(img);

                // Update album detail
                if (img.getAlbum() > 0) {
                    List<AlbumDetail> albumDetails = albumDetailDao.findByColumNames(
                            new String[]{"ImageId", "AlbumId"},
                            new Object[] {imgId, img.getAlbum()});
                    if (albumDetails == null || albumDetails.size() == 0) { // existed
                        AlbumDetail ad = new AlbumDetail(img.getAlbum(), imgId);
                        albumDetailDao.add(ad);
                    }
                }
                json.put("result", "OK");
            } catch (Exception ex) {
                Logger.getLogger(ImageHandler.class.getName())
                        .log(Level.SEVERE, null, ex);
                json.put("result", "ERROR: " + ex.toString());
            }
            //JSONArray jsons = getAllImages();
            HandlerUtil.writeResponse(json.toJSONString(), request, response);
        } else if (cmd.equalsIgnoreCase("get_images")) {
            JSONArray jsons = getAllImages();
            HandlerUtil.writeResponse(jsons.toJSONString(), request, response);
        } else if (cmd.equalsIgnoreCase("get_albums")) {
            JSONArray jsons = getAllAlbums();
            HandlerUtil.writeResponse(jsons.toJSONString(), request, response);
        } else if (cmd.equalsIgnoreCase("add_album")) {
            String data = request.getParameter("data");
            JSONObject json = new JSONObject();
            try {
                Album album = getAlbum(data);
                List<Album> albums = albumDao.findByColumName("Name", album.getName());
                if (albums != null && albums.size() > 0) {
                    json.put("result", "Album already existed");
                } else {
                    albumDao.add(album);
                    json.put("result", "OK");
                }
            } catch (Exception ex) {
                Logger.getLogger(ImageHandler.class.getName()).log(Level.SEVERE, null, ex);
            }
            HandlerUtil.writeResponse(json.toJSONString(), request, response);
        }
    }
    
    /**
     * Retrieve an Image from json string
     * @param data json data
     * @return Image from json data, or null if data format
     *      is incorrect.
     * @throws ParseException an PerseException should occur
     */
    private Image getImage(String data) throws ParseException {
        JSONObject jsonObj = (JSONObject) parser.parse(data);
        Image img = new Image();
        img.setUrl(jsonObj.get("URL").toString());
        img.setComment(jsonObj.get("COMMENT").toString());
        try {
            img.setAlbum(Integer.parseInt(jsonObj.get("ALBUM").toString()));
        } catch (Exception ex) {
            img.setAlbum(-1);
        }
        
        return img;
    }
    
    /**
     * Retrieve an Album from json string
     * @param data json data
     * @return Album from json data, or null if data format
     *      is incorrect.
     * @throws ParseException an PerseException should occur
     */
    private Album getAlbum(String data) throws ParseException {
        JSONObject jsonObj = (JSONObject) parser.parse(data);
        Album album = new Album();
        album.setName(jsonObj.get("name").toString());
        album.setAuthor(jsonObj.get("author").toString());
        Date today = new Date();
        album.setCreated(today);
        album.setLastModify(today);
        
        return album;
    }
    
    /**
     * Retrieve an json array object, include
     * information about all image existed in
     * system db
     * @return JSONArray
     */
    private JSONArray getAllImages() {
        JSONArray jsons = new JSONArray();
        List<Image> images = null;
        try {
            images = imgDao.findAll();
        } catch (Exception ex) {
            Logger.getLogger(ImageHandler.class.getName())
                    .log(Level.SEVERE, null, ex);
        }
        if ((images != null) && !images.isEmpty()) {
            for (Image img : images) {
                JSONObject json = new JSONObject();
                json.put("URL", img.getUrl());
                json.put("COMMENT", img.getComment());

                jsons.add(json);
            }
        }
        
        return jsons;
    }
    
    private JSONArray getAllAlbums() {
        JSONArray jsons = new JSONArray();
        List<Album> albums = null;
        try {
            albums = albumDao.findAll();
        } catch (Exception ex) {
            Logger.getLogger(ImageHandler.class.getName())
                    .log(Level.SEVERE, null, ex);
        }
        if ((albums != null) && !albums.isEmpty()) {
            for (Album al : albums) {
                JSONObject json = new JSONObject();
                json.put("id", al.getId());
                json.put("name", al.getName());

                jsons.add(json);
            }
        }
        
        return jsons;
    }
}
